package com.fzy.leetcode.editor.cn;
//2023-03-18 19:50:43
//给你一个 m x n 的矩阵 board ，由若干字符 'X' 和 'O' ，找到所有被 'X' 围绕的区域，并将这些区域里所有的 'O' 用 'X' 填充
//。
//
// 
// 
// 
// 
// 
//
// 示例 1： 
// 
// 
//输入：board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O",
//"X","X"]]
//输出：[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]
//解释：被围绕的区间不会存在于边界上，换句话说，任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上，或不与边界上的 'O' 相连的 'O' 最终都
//会被填充为 'X'。如果两个元素在水平或垂直方向相邻，则称它们是“相连”的。
// 
//
// 示例 2： 
//
// 
//输入：board = [["X"]]
//输出：[["X"]]
// 
//
// 
//
// 提示： 
//
// 
// m == board.length 
// n == board[i].length 
// 1 <= m, n <= 200 
// board[i][j] 为 'X' 或 'O' 
// 
//
// Related Topics 深度优先搜索 广度优先搜索 并查集 数组 矩阵 👍 937 👎 0

import java.util.LinkedList;
import java.util.Queue;

class SurroundedRegions {
    public static void main(String[] args) {
        //创建该题目的对象方便调用
        Solution solution = new SurroundedRegions().new Solution();
    }
    //leetcode submit region begin(Prohibit modification and deletion)
class Solution {

    int[] dx = {-1,1,0,0};
    int[] dy = {0,0,1,-1};
    public void solve(char[][] board) {
        int n = board.length;
        if(n == 0){
            return;
        }
        int m = board[0].length;

        Queue<int[]> queue = new LinkedList<>();
        //将边境的'O'设置为A并放入队列
        //A为不可修改
        for(int i = 0;i<n;i++){
            if(board[i][0] == 'O'){
                queue.offer(new int[]{i,0});
                board[i][0] = 'A';
            }
            if(board[i][m-1] == 'O'){
                queue.offer(new int[]{i,m-1});
                board[i][m-1] = 'A';
            }
        }

        for(int i = 1;i<m-1;i++){
            if(board[0][i] =='O'){
                queue.offer(new int[]{0,i});
                board[0][i] = 'A';
            }
            if(board[n-1][i] == 'O'){
                queue.offer(new int[]{n-1,i});
                board[n-1][i] = 'A';
            }
        }
        //以每个边界为起点开始进行BFS
        while (!queue.isEmpty()){
            int[] cell = queue.poll();
            int x = cell[0],y = cell[1];
            for(int i = 0;i<4;i++){  //遍历四个方向
                int mx = x+dx[i];
                int my = y+dy[i];

                //越界跳过本次操作
                if(mx<0 || my<0 || mx>=n || my >=m || board[mx][my] != 'O'){
                    continue;
                }
                //将于边界连接的点入队
                queue.offer(new int[]{mx,my});
                //标记为不能修改量
                board[mx][my] = 'A';
            }
        }

        //循环遍历整个二维数组，将 O 转变为 X
        for(int i = 0;i<n;i++){
            for(int j = 0;j<m;j++){
                if(board[i][j] == 'A'){
                    board[i][j] = 'O';
                }else if(board[i][j] == 'O'){
                    board[i][j] = 'X';
                }
            }
        }


    }
}
//leetcode submit region end(Prohibit modification and deletion)

}